package cn.edu.mju.dilidili.common.utils;

import cn.edu.mju.dilidili.common.exception.JWTTimeInvalidException;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Map;

@Slf4j
public class ConnectUtil {
    public static ServletRequestAttributes getServletRequestAttributes() {
        return (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    }

    private static HttpSession getSession() {
        // 会导致刷新cookie
        return getRequest().getSession();
    }

    public static HttpServletRequest getRequest() {
        return getServletRequestAttributes().getRequest();
    }

    public static String getSessionId() {
        /*
         * 这他妈是什么情况
         * 一晚上一堆session的问题
         * 先是一直变来变去
         * 突然就不变了
         * 我还搁那开心呢
         * 突然发现不变的原因居然是不生成了
         * 迫不得已全部重写有相关调用的地方
         * 草草草草草草草草草草
         *
         * 好得很好的很
         * 又正常了
         * 那就用原来的
         *
         * 非常棒
         * 一换马上就两个问题双开
         * 浏览器一直换session
         * Apifox得不到session
         * 别想用JSESSIONID了!!!
         * */
        String res = getCookie("Session");
        if (res == null) {
            res = IdUtil.fastSimpleUUID();
            addCookie("Session", res);
        }
        return res;
//        return getCookie("JSESSIONID"); // 不可能执行的语句
    }

    public static String getAddress() {
        return getRequest().getRemoteAddr();
    }

    public static HttpServletResponse getResponse() {
        return getServletRequestAttributes().getResponse();
    }

    public static void addCookie(String k, String v) {
        Cookie cookie = new Cookie(k, v);
        cookie.setPath("/");
        getResponse().addCookie(cookie);
    }

    public static void delCookie(String k) {
        Cookie cookie = new Cookie(k, null);
        cookie.setPath("/");
        cookie.setMaxAge(0);
        getResponse().addCookie(cookie);
    }

    public static String getCookie(String k) {
        Cookie[] cookies = getRequest().getCookies();
        if (cookies == null) {
            return null;
        }
        for (Cookie i : cookies) {
            if (i.getName().equals(k)) {
                return i.getValue();
            }
        }
        return null;
    }

    public static JWT putJWT(Map<String, ?> payloads) {
//        log.info("putJWT");
        JWT jwt = new JWT();
        jwt.addPayloads(payloads); // 添加荷载
        jwt.setIssuedAt(DateUtil.date()); // 设置签发时间
        jwt.setExpiresAt(DateUtil.offsetDay(DateUtil.date(), 5));// 设置过期时间, 默认五天后过期
        jwt.setKey(FinalVariable.JWT_KEY_BYTE);
        addCookie(FinalVariable.AUTHORIZATION, jwt.sign());
        return jwt;
    }

    /*
     * 获取jwt, 如果jwt未过期且少于期限, 则更新过期时间
     */
    public static JWT getJWT() {
//        log.info("getJWT");
        JWT jwt = JWTUtil.parseToken(getCookie(FinalVariable.AUTHORIZATION));
        jwt.setKey(FinalVariable.JWT_KEY_BYTE);
        if (!(jwt.verify() && jwt.validate(15))) {
            throw new JWTTimeInvalidException();
        }
        if (DateUtil.compare(DateUtil.date((Integer) jwt.getPayload(JWT.EXPIRES_AT) * 1000L), DateUtil.offsetDay(DateUtil.date(), 2)) <= 0) {
            jwt = putJWT(jwt.getPayloads());
        }// 如果过期时间在两天之内, 更新jwt
        return jwt;
    }


    public static void addHeader(String k, String v) {
        HttpServletResponse response = getResponse();
        response.addHeader(k, v);
        response.addHeader("Access-Control-Expose-Headers", k);
    }
}
